package pers.qianyu.module.system.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.asymmetric.RSA;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import pers.qianyu.module.core.comm.HttpResult;
import pers.qianyu.module.core.constants.TokenConstants;
import pers.qianyu.module.core.domain.system.dto.LoginDTO;
import pers.qianyu.module.core.domain.system.vo.SysUserVO;
import pers.qianyu.module.logging.annotation.ControllerLog;
import pers.qianyu.module.logging.enums.BusinessType;
import pers.qianyu.module.system.service.AuthenticateService;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Api(tags = "认证相关接口")
@Validated
@RestController
@RequestMapping("/system-serv")
public class AuthController {
    @Autowired
    private DefaultKaptcha defaultKaptcha;
    @Autowired
    private AuthenticateService authenticateService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @ApiOperation("根据token获取用户信息")
    @ControllerLog(businessType = BusinessType.QUERY)
    @GetMapping("/auth")
    public HttpResult<SysUserVO> getUserInfoByToken(@NotBlank(message = "token不能为空") String token) {
        SysUserVO sysUserVO = authenticateService.getUserInfoByToken(token);
        return HttpResult.okWithData(sysUserVO);
    }

    @ApiOperation("登录接口")
    @ControllerLog(businessType = BusinessType.LOGIN)
    @PostMapping(value = "/login")
    public HttpResult<?> login(@RequestBody LoginDTO loginDTO) {
        String token = authenticateService.login(loginDTO);
        return HttpResult.okWithData(token);
    }

    @ApiOperation("退出登录")
    @ControllerLog(businessType = BusinessType.LOGOUT)
    @GetMapping(value = "/logout")
    public HttpResult<?> logout(String token) {
        authenticateService.delToken(token);
        return HttpResult.okWithMessage("退出登录成功");
    }

    @ApiOperation("获取验证码")
    @ControllerLog(businessType = BusinessType.QUERY)
    @GetMapping("/captcha.jpg")
    public void captcha(HttpServletResponse res) throws IOException {
        res.setHeader("Cache-Control", "no-store, no-cache");
        res.setContentType("image/jpeg");
        // 生成文字验证码
        String text = defaultKaptcha.createText();
        // 生成图片验证码
        BufferedImage image = defaultKaptcha.createImage(text);
        // 保存到验证码到 redis，保存五分钟
        String uuid = IdUtil.fastSimpleUUID();
        redisTemplate.opsForValue().set(TokenConstants.UUID_PREFIX + uuid,
                text, TokenConstants.CODE_EXPIRE_TIME);
        // 将 uuid 放入响应头
        res.setHeader("uuid", uuid);
        // RSA 加密
        RSA rsa = new RSA();
        redisTemplate.opsForValue().set(TokenConstants.RSA_PUB_PREFIX + uuid,
                rsa.getPrivateKeyBase64(), TokenConstants.CODE_EXPIRE_TIME);
        res.setHeader("sign", rsa.getPublicKeyBase64());
        // 写回图片内容
        ServletOutputStream out = res.getOutputStream();
        ImageIO.write(image, "jpg", out);
        out.close();
    }
}
